package cn.iocoder.yudao.module.member.bonus.service.app;

import cn.iocoder.yudao.framework.business.basic.dao.repository.SerialNoRedisRepository;
import cn.iocoder.yudao.framework.business.order.service.AppOrderBaseService;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.infrastructure.config.ConfigApiV2;
import cn.iocoder.yudao.module.api.infrastructure.config.dto.MemberConfigRespDTO;
import cn.iocoder.yudao.module.api.member.bonus.vo.BonusOrderVO;
import cn.iocoder.yudao.module.api.pay.bill.enums.BillTypeEnum;
import cn.iocoder.yudao.module.api.pay.order.PayOrderApi;
import cn.iocoder.yudao.module.api.pay.order.dto.PayOrderCreateDTO;
import cn.iocoder.yudao.module.member.bonus.dao.BonusOrderMapper;
import cn.iocoder.yudao.module.member.bonus.mq.BonusProducer;
import cn.iocoder.yudao.module.member.bonus.pojo.dto.BonusOrderSubmitDTO;
import cn.iocoder.yudao.module.member.bonus.pojo.po.BonusOrder;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static cn.iocoder.yudao.module.api.infrastructure.ConfigConstants.CONFIG_MEMBER;
import static cn.iocoder.yudao.module.api.member.ConfigConstants.BONUS_ORDER_NO_PREFIX;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * 服务
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/05/09
 */
@Service
public class AppBonusOrderService extends AppOrderBaseService<BonusOrder, BonusOrderVO, BonusOrderSubmitDTO> {
    @Resource
    private BonusOrderMapper bonusOrderMapper;

    @Resource
    private SerialNoRedisRepository serialNoRedisRepository;
    @Resource
    private BonusProducer bonusProducer;

    @Resource
    private AppBonusUserService appBonusUserService;

    @Resource
    private ConfigApiV2 configApiV2;
    @Resource
    private PayOrderApi payOrderApi;

    @Override
    public BonusOrderMapper getInjectedMapper() {
        return bonusOrderMapper;
    }

    @Nonnull
    @Override
    protected BonusOrder onOrderCreateBefore(@Nonnull BonusOrderSubmitDTO dto, @Nonnull Long userId) {
        MemberConfigRespDTO memberConfigRespDTO = configApiV2.getConfig(CONFIG_MEMBER, MemberConfigRespDTO.class);
        // 构建订单信息
        BonusOrder order = new BonusOrder();
        order.setUserId(userId);
        order.setDays(memberConfigRespDTO.getBonusBenefitDays());
        order.setPrice(memberConfigRespDTO.getBonusBenefitPrice());
        order.setSnapshot("{\"bonusBenefitDays\": %d, \"bonusBenefitPrice\": %d}".formatted(memberConfigRespDTO.getBonusBenefitDays(), memberConfigRespDTO.getBonusBenefitPrice()));
        order.setTradeNo(serialNoRedisRepository.generateNo(BONUS_ORDER_NO_PREFIX));
        order.setNote("购买【%s天】的分红权".formatted(memberConfigRespDTO.getBonusBenefitDays()));
        return order;
    }

    @Async
    @Override
    public void createPayOrder(@Nonnull BonusOrder order) {
        PayOrderCreateDTO createDTO = new PayOrderCreateDTO();
        createDTO.setTradeNo(order.getTradeNo());
        createDTO.setSubject(BillTypeEnum.PAY_BONUS_BENEFIT.getName());
        createDTO.setBody(order.getNote());
        createDTO.setPrice(order.getPrice());
        String payNo = payOrderApi.createOrder(createDTO);
        // 创建付款单据后再回来更新业务订单的支付单号
        BonusOrder updateObj = new BonusOrder();
        updateObj.setId(order.getId());
        updateObj.setPayNo(payNo);
        getInjectedMapper().updateById(updateObj);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    protected void onPaidAfter(BonusOrder order) {
        appBonusUserService.updateWhenPaid(order);
        bonusProducer.sendBonusOrderPaidMessage(BeanUtils.toBean(order, BonusOrderVO.class));
    }

}
